package com.simple.json.clazz;

import java.lang.reflect.Field;
import java.util.HashMap;

import org.json.JSONObject;

import com.simple.json.Util;
import com.simple.json.clazz.basic.BasicBooleanClass;
import com.simple.json.clazz.basic.BasicDoubleClass;
import com.simple.json.clazz.basic.BasicFloatClass;
import com.simple.json.clazz.basic.BasicIntClass;
import com.simple.json.clazz.basic.BasicLongClass;
import com.simple.json.clazz.basic.BooleanClass;
import com.simple.json.clazz.basic.DoubleClass;
import com.simple.json.clazz.basic.FloatClass;
import com.simple.json.clazz.basic.IntegerClass;
import com.simple.json.clazz.basic.LongClass;
import com.simple.json.clazz.basic.StringClass;
import com.simple.json.clazz.external.ArrayListClass;
import com.simple.json.clazz.external.UserDefineClass;

public class ValueClassWorkerChain {

	private static ValueClassWorkerChain worker;
	private HashMap<Class<?>, ClassInterface> classesMap = new HashMap<Class<?>, ClassInterface>();

	private ValueClassWorkerChain() {
		// basic
		classesMap.put(BasicBooleanClass.getInstance().getProcessClassType(),
				BasicBooleanClass.getInstance());
		classesMap.put(BasicDoubleClass.getInstance().getProcessClassType(),
				BasicDoubleClass.getInstance());
		classesMap.put(BasicFloatClass.getInstance().getProcessClassType(),
				BasicFloatClass.getInstance());
		classesMap.put(BasicLongClass.getInstance().getProcessClassType(),
				BasicLongClass.getInstance());
		classesMap.put(BasicIntClass.getInstance().getProcessClassType(),
				BasicIntClass.getInstance());
		classesMap.put(BooleanClass.getInstance().getProcessClassType(),
				BooleanClass.getInstance());
		classesMap.put(IntegerClass.getInstance().getProcessClassType(),
				IntegerClass.getInstance());
		classesMap.put(StringClass.getInstance().getProcessClassType(),
				StringClass.getInstance());
		classesMap.put(DoubleClass.getInstance().getProcessClassType(),
				DoubleClass.getInstance());
		classesMap.put(FloatClass.getInstance().getProcessClassType(),
				FloatClass.getInstance());
		classesMap.put(LongClass.getInstance().getProcessClassType(),
				LongClass.getInstance());
		// external
		classesMap.put(ArrayListClass.getInstance().getProcessClassType(),
				ArrayListClass.getInstance());
	}

	public static ValueClassWorkerChain getInstance() {
		if (worker == null) {
			synchronized (ValueClassWorkerChain.class) {
				if (worker == null) {
					worker = new ValueClassWorkerChain();
				}
			}
		}

		return worker;
	}

	@SuppressWarnings("unchecked")
	public <T> T getRightValue(Object orignalValue, Class<T> clazz) {
		ClassInterface baseClassInterface = classesMap.get(clazz);
		if (baseClassInterface != null) {
			return (T) baseClassInterface.getRightValue(orignalValue);
		} else {
			Util.logerr("no mach Class to process this class : "
					+ clazz.getName());
			return null;
		}
	}

	/**
	 * 将JSONObject赋值给实例的成员变量
	 * 
	 * @param targetObject
	 *            最终要赋值的对象
	 * @param targetField
	 *            最终要赋值对象的成员变量
	 * @param value
	 *            原始的JSONObject值
	 * @return 是否处理成功。如果成员变量的类型不是{@link ValueClassWorkerChain}能够处理的类型，则返回false
	 */
	public <T> boolean setRightValueToFieldFromJson(T targetObject,
			Field targetField, JSONObject value) {
		ClassInterface baseClassInterface = classesMap.get(targetField
				.getType());
		if (baseClassInterface != null) {
			return baseClassInterface.setRightValueToField(targetObject,
					targetField, value);
		} else {
			boolean isUserDefine = UserDefineClass.getInstance()
					.setRightValueToField(targetObject, targetField, value);
			if (!isUserDefine) {
				Util.logerr("成员变量 " + targetField.getName() + " 的类型是 ："
						+ targetField.getType().getName() + "， 不是基本数据类型，未能处理！");
				return false;
			} else {
				return true;
			}
		}
	}

}
